﻿

using Microsoft.Extensions.Options;
using UtilLib;
using static System.Net.Mime.MediaTypeNames;

namespace SvCore;

public static partial class Core
{
    public static ManualResetEvent ManualStop = new ManualResetEvent(false);
    public static List<ISv> ListSv = new();
    public static List<ISv> ListSvInit = new();
    public static DateTime Now = DateTime.Now;
    public static Dictionary<EvtType, Action<Evt>> DictEvt = new();
    public static ConcurrentQueue<Evt> QueueEvt = new ConcurrentQueue<Evt>();
    public static List<IExit> ListExit = new();

    public static void AddSv(params ISv[] svs)
    {
        ListSv.AddRange(svs);
    }
    public static void AddExit(params IExit[] exits)
    {
        ListExit.AddRange(exits);
    }

    public static void Start()
    {
        foreach (var item in ListSv)
        {
            ListSvInit.Add(item);
            item.Init();
            Task.Run(() => item.Run());
        }
        WaitStop();
        Util.Show("SvCore.Start ----------- 服务器启动成功");
        while (true)
        {
            if (ManualStop.WaitOne(10))
            {
                loger.Info("进程退出。。。");
                Thread.Sleep(5000);
                break;
            }

            Now = DateTime.Now;
            HandleEvt();

            Thread.Sleep(10);
        }
    }
    public static void WaitStop()
    {
        AppDomain appd = AppDomain.CurrentDomain;
        appd.ProcessExit += (s, e) =>
        {
            loger.Info("检测到进程退出。。。");
            Exit();
            ManualStop.Set();
        };
        Console.CancelKeyPress += (sender, e) =>
        {
            //e.Cancel = true; //true: 不导致退出。false: 会导致退出
            //System.Console.WriteLine("You have Press Ctrl+C");
            e.Cancel = true;
            loger.Info("检测到 Press Ctrl+C 。。。");
            Exit();
            ManualStop.Set();
        };
    }
    public static void Exit()
    {
        foreach (var item in ListExit)
        {
            item.Destroy();
        }
    }
    // 解析命令行参数
    public static void ParseArgs(string[] args)
    {
        var stringargs = string.Join(" ", args);
        Util.Show($"使用程序 命令行参数 {stringargs}");
        //string cmdargs = "";
        //foreach (var arg in args)
        //{
        //    //服务器
        //    if (arg.StartsWith("sv="))
        //    {
        //        var argtemp = arg.Substring(3);
        //        SvInfo.ConfigId = argtemp.ToInt();
        //        cmdargs += $" 服务器ID{SvInfo.ConfigId}";
        //    }
        //}
        // 命令行参数
        SvInfo.Options = Parser.Default.ParseArguments<SvOptions>(args)
            .WithNotParsed(error => throw new Exception($"命令行格式错误! {error}"))
            .Value;

        SvInfo.ConfigId = SvInfo.Options.ConfigId;

        Util.Show($"命令行参数 服务器ID:{SvInfo.ConfigId}");
    }
    public static void InitLog()
    {
        bool log4net_init = false;
        while (!log4net_init)
        {
            try
            {
                var log4netXmlFs = new FileStream("log4net.config", FileMode.Open);
                var log4netXmlSr = new StreamReader(log4netXmlFs);
                var log4netXmlStr = log4netXmlSr.ReadToEnd();
                log4netXmlStr = log4netXmlStr.Replace("$$$$$", $"{CoreInfo.ServerType}{CoreInfo.ConfigId}");
                log4netXmlSr.Close();
                var log4netXmlDoc = new XmlDocument();
                log4netXmlDoc.LoadXml(log4netXmlStr);
                var log4netRootElement = log4netXmlDoc.DocumentElement;
                loger.Configure("NETCoreRepository", log4netRootElement);
                log4net_init = true;
            }
            catch (Exception ex)
            {
                Util.ShowError($"初始化日志系统错误 {ex.Message}");
                break;
            }
        }
    }
    public static void HandleEvt()
    {
        if (QueueEvt.TryDequeue(out var evt))
        {
            if (DictEvt.TryGetValue(evt.Type, out var act))
            {
                act(evt);
            }
        }
    }
}
